home *** CD-ROM | disk | FTP | other *** search
/ Windows News 2010 Summer - Disc 1 / WN_Ete2010_CD1.iso / Onglet5 / Weezo / Weezo setup.exe / {code_appDir} / www / includes / zip.php < prev   
PHP Script  |  2010-05-19  |  10KB  |  292 lines

  1. <?php
  2. // Class definition found at http://www.zend.com/zend/spotlight/creating-zip-files3.php
  3. // Some alterations to the original posted code were made in order to get everything working properly
  4.  
  5. // Other modification have been made to include Weezo transfer speed limitation
  6.  
  7. // http://www.pkware.com/documents/casestudies/APPNOTE.TXT
  8.  
  9. /**
  10.  * @desc zip compression class
  11.  *         difference with zipfile class : real-time zip generation, no memory buffering, direct send to output
  12.  *
  13.  */
  14. class zipfile2
  15. {
  16.     var $datasec = array();
  17.     var $ctrl_dir = array();
  18.     var $old_offset = 0;
  19.  
  20.     var $nbDatasec=0;
  21.     var $nbCtrl_dir=0;
  22.     var $lenData=0;
  23.     var $lenCtrl_dir=0;
  24.  
  25.     var $downloadSpeedLimit=0;
  26.     var $speedLimit;
  27.  
  28.     var $uncompressedSize=0;
  29.     var $readSize=0;
  30.     var $t=null; // Transfer
  31.  
  32.     var $compressionLevel=9; // ZLib Compression (0 uncompressed - 9 max compression)
  33.  
  34.     function setSpeedLimit($sl){
  35.         if(!is_numeric($sl)) return false;
  36.         $this->speedLimit=new transferLimitation($sl*1024);
  37.         $this->downloadSpeedLimit=$sl*1024;
  38.     }
  39.  
  40.     /**
  41.      * @desc Encode filename in CP850
  42.      *
  43.      * @param string $name: basename encoded in system codepage
  44.      * @return string
  45.      */
  46.     function encode_filename($name){
  47.         return $name;
  48.         $l=strlen($name);
  49.         for ($i=0;$i<$l;$i++){
  50.             $c=@iconv(cfMGetVar('systemCodepage'),'850',substr($name,$i,1));
  51.             if(strlen($c)) $name[$i]=$c; //else $name[$i]='-';
  52.         }
  53.         return $name;
  54.     }
  55.  
  56.     /**
  57.      * @desc Add an empty directory to archive
  58.      *
  59.      * @param string $completeFilename: complete path
  60.      * @param string $name: path name beetween zip root and current dir (encoded in system codepage)
  61.      */
  62.     function add_dir($completeFilename, $name) {
  63.         $name = str_replace("\\", "/", $name);
  64.         $encodedName=$this->encode_filename($name);
  65.  
  66.         // Local file header
  67.         $fr = "\x50\x4b\x03\x04";// local file header signature
  68.         $fr .= "\x14\x00";// version needed to extract
  69.         $fr .= "\x00\x00";// general purpose bit flag
  70.         $fr .= "\x08\x00";// compression method
  71.         $time = getdate(filemtime($completeFilename));
  72.         $fr .= pack('vv',2048*$time['hours']+32*$time['minutes']+floor($time['seconds']/2),512*($time['year']-1980)+32*$time['mon']+$time['mday']); // MS-DOS formated modification time & date
  73.         $fr .= pack("V",0);// crc-32
  74.         $fr .= pack("V",0);// compressed size
  75.         $fr .= pack("V",0);// uncompressed size
  76.         $fr .= pack("v", strlen($encodedName) );// file name length
  77.         $fr .= pack("v", 0 );// extra field length
  78.         $fr .= $encodedName;// file name
  79.         /*
  80.         $fr .= pack("V", 0);
  81.         $fr .= pack("V", 0);
  82.         $fr .= pack("V", 0);
  83.         */
  84. /*
  85.         $fr .= pack("V",$crc); // crc-32
  86.         $fr .= pack("V",$c_len); // compressed size
  87.         $fr .= pack("V",$unc_len); // uncompressed size
  88.         $fr .= pack("v", strlen($encodedName)); // file name length
  89.         $fr .= pack("v", 0 ); // extra field length
  90.         $fr .= $encodedName; // file name
  91.         $fr .= $zdata; // compressed data
  92. */
  93.         $this->nbDatasec++;
  94.         $this->lenData+=strlen($fr);
  95.         if(!$this->downloadSpeedLimit){
  96.             echo $fr;
  97.             flush();
  98.         }
  99.         else{
  100.             $p=0;
  101.             $bufferSize=min(16384,$this->downloadSpeedLimit);
  102.             while ($p<strlen($fr)) {
  103.                 if($p+$bufferSize>strlen($fr)) {
  104.                     echo substr($fr,$p);
  105.                     $this->speedLimit->addData(strlen($fr)-$p);
  106.                 }
  107.                 else{
  108.                     echo substr($fr,$p,$bufferSize);
  109.                     $this->speedLimit->addData($bufferSize);
  110.                 }
  111.                 flush();
  112.                 $p+=$bufferSize;
  113.             }
  114.         }
  115.  
  116.         $new_offset = $this->lenData;
  117.  
  118.         // Central directory header
  119.         $cdrec = "\x50\x4b\x01\x02"; // local file header signature
  120.         $cdrec .="\x14\x0b"; // version made by
  121.         $cdrec .="\x14\x00"; // version needed to extract
  122.         $cdrec .="\x00\x00"; // general purpose bit flag
  123.         $cdrec .="\x08\x00"; // compression method
  124.         $cdrec .= pack('vv',2048*$time['hours']+32*$time['minutes']+floor($time['seconds']/2),512*($time['year']-1980)+32*$time['mon']+$time['mday']); // MS-DOS formated modification time & date
  125.         $cdrec .= pack("V",0); // crc-32
  126.         $cdrec .= pack("V",0); // compressed size
  127.         $cdrec .= pack("V",0); // uncompressed size
  128.         $cdrec .= pack("v", strlen($encodedName) ); // file name length
  129.         $cdrec .= pack("v", 0 ); // extra field length
  130.         $cdrec .= pack("v", 0 ); // file comment length
  131.         $cdrec .= pack("v", 0 ); // disk number start
  132.         $cdrec .= pack("v", 0 ); // internal file attributes
  133.         $cdrec .= pack("V", 16 ); // external file attributes
  134.         $cdrec .= pack("V", $this -> old_offset ); // relative offset of local header
  135.         $cdrec .= $encodedName; // file name
  136.  
  137.         $this -> ctrl_dir[] = $cdrec;
  138.         $this->nbCtrl_dir++;
  139.         $this->nbCtrl_dir+=strlen($cdrec);
  140.         $this -> old_offset = $new_offset;
  141.         return;
  142.     }
  143.  
  144.     /**
  145.      * @desc Add a file to zip archive
  146.      *
  147.      * @param string $completeFilename: file path & name
  148.      * @param string $name
  149.      * @return boolean true if OK, false if file couldn't be opened
  150.      */
  151.     function add_file($completeFilename, $name) {
  152.         $fp = @fopen($completeFilename,"rb");
  153.         if(!$fp) return false;
  154.         if(filesize($completeFilename)>0) $data = fread($fp,filesize($completeFilename)); else $data='';
  155.         fclose($fp);
  156.         $name = str_replace("\\", "/", $name);
  157.         $time = getdate(filemtime($completeFilename));
  158.  
  159.         $unc_len = strlen($data);
  160.         $crc = crc32($data);
  161.         $zdata = gzcompress($data,$this->compressionLevel);
  162.         $zdata = substr ($zdata, 2, -4);
  163.         $c_len = strlen($zdata);
  164.  
  165.         $encodedName=$this->encode_filename($name);
  166.  
  167.         // Local file header
  168.         $fr = "\x50\x4b\x03\x04";// local file header signature
  169.         $fr .= "\x14\x00";// version needed to extract
  170.         $fr .= "\x02\x00";// general purpose bit flag
  171.         $fr .= "\x08\x00";// compression method
  172.  
  173.         $fr .= pack('vv',2048*$time['hours']+32*$time['minutes']+floor($time['seconds']/2),512*($time['year']-1980)+32*$time['mon']+$time['mday']); // MS-DOS formated modification time & date
  174.  
  175.         $fr .= pack("V",$crc); // crc-32
  176.         $fr .= pack("V",$c_len); // compressed size
  177.         $fr .= pack("V",$unc_len); // uncompressed size
  178.         $fr .= pack("v", strlen($encodedName)); // file name length
  179.         $fr .= pack("v", 0 ); // extra field length
  180.         $fr .= $encodedName; // file name
  181.         $fr .= $zdata; // compressed data
  182.  
  183.  
  184.         // Remove Thumbs.db hidden files from archive
  185.         if(basename($name)=='Thumbs.db' && substr(customFileAttributes($completeFilename),0,1)=='H') $fr='';
  186.         // Other files
  187.         else{
  188.             $this->nbDatasec++;
  189.             $this->lenData+=strlen($fr);
  190.         }
  191.  
  192.         // If no speed limit, directly output created zip file
  193.         if(!$this->downloadSpeedLimit){
  194.             echo $fr;
  195.             flush();
  196.             cfPingUpdate(100);
  197.             $this->readSize+=$unc_len;
  198.             // Transfert monitoring
  199.             if($this->t && (!$this->t->exists() || $this->t->status==9)) exit; // Transfert stopped : quit
  200.              if($this->t && $this->uncompressedSize) {
  201.                 $this->t->updateProgress($this->readSize/$this->uncompressedSize,true);
  202.                 $this->t->commitToFile(false,false);
  203.             }
  204.         }
  205.         else{
  206.             $p=0;
  207.             $bufferSize=min(16384,$this->downloadSpeedLimit);
  208.             if($fr) $zipRatio=$unc_len/strlen($fr);
  209.             while ($p<strlen($fr)) {
  210.                 if($p+$bufferSize>strlen($fr)) {
  211.                     echo substr($fr,$p);
  212.                     $this->speedLimit->addData(strlen($fr)-$p);
  213.                 }
  214.                 else{
  215.                     echo substr($fr,$p,$bufferSize);
  216.                     $this->speedLimit->addData($bufferSize);
  217.                 }
  218.                 flush();
  219.                 cfPingUpdate(10);
  220.                 $p+=$bufferSize;
  221.                 // Transfert monitoring
  222.                 if($this->t && (!$this->t->exists() || $this->t->status==9)) exit; // Transfert stopped : quit
  223.                 if($this->t && $this->uncompressedSize){
  224.                     $this->t->updateProgress(($this->readSize+$p*$zipRatio)/$this->uncompressedSize,true);
  225.                     $this->t->commitToFile(false,false);
  226.                 }
  227.             }
  228.             $this->readSize+=$unc_len;
  229.             // Transfert monitoring
  230.             if($this->t && (!$this->t->exists() || $this->t->status==9)) exit; // Transfert stopped : quit
  231.             if($this->t && $this->uncompressedSize) {
  232.                 $this->t->updateProgress($this->readSize/$this->uncompressedSize,true);
  233.                 $this->t->commitToFile(false,false);
  234.             }
  235.         }
  236.  
  237.         // If removed Thumbs.db, proceed
  238.         if(!$fr) return true;
  239.  
  240.         $new_offset = $this->lenData;
  241.  
  242.         // Central directory header
  243.         $cdrec = "\x50\x4b\x01\x02";// local file header signature
  244.         $cdrec .="\x14\x0b";// version made by
  245.         $cdrec .="\x14\x00";// version needed to extract
  246.  
  247.         $cdrec .="\x02\x00";// general purpose bit flag
  248.  
  249.         $cdrec .="\x08\x00";// compression method
  250.         $cdrec .= pack('vv',2048*$time['hours']+32*$time['minutes']+floor($time['seconds']/2),512*($time['year']-1980)+32*$time['mon']+$time['mday']); // MS-DOS formated modification time & date
  251.         $cdrec .= pack("V",$crc); // crc-32
  252.         $cdrec .= pack("V",$c_len); // compressed size
  253.         $cdrec .= pack("V",$unc_len); // uncompressed size
  254.         $cdrec .= pack("v", strlen($encodedName)); // file name length
  255.         $cdrec .= pack("v", 0 ); // extra field length
  256.         $cdrec .= pack("v", 0 ); // file comment length
  257.         $cdrec .= pack("v", 0 ); // disk number start
  258.         $cdrec .= pack("v", 0 ); // internal file attributes
  259.         $cdrec .= pack("V", 32 ); // external file attributes
  260.         $cdrec .= pack("V", $this -> old_offset ); // relative offset of local header
  261.  
  262.         $this -> old_offset = $new_offset;
  263.  
  264.         $cdrec .= $encodedName;
  265.         $this->nbCtrl_dir++;
  266.         $this->nbCtrl_dir+=strlen($cdrec);
  267.  
  268.         $this -> ctrl_dir[] = $cdrec;
  269.         return true;
  270.     }
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.     // End of central directory record
  278.     function file() {
  279.         $ctrldir = implode("", $this -> ctrl_dir);
  280.         echo
  281.             $ctrldir .
  282.             "\x50\x4b\x05\x06" .//  end of central dir signature
  283.             "\x00\x00\x00\x00" . // number of this disk + number of this disk with the start of the central directory
  284.             pack("v", sizeof($this -> ctrl_dir)) .// total number of entries in the central directory
  285.             pack("v", sizeof($this -> ctrl_dir)) .// total number of entries in the central directory on this disk
  286.             pack("V", strlen($ctrldir)) . // size of the central directory
  287.             pack("V", $this->lenData) . // offset of start of central directory
  288.             "\x00\x00";
  289.     }
  290. }
  291. ?>
  292.